import ijeoma.tween.*;
import ijeoma.easing.*;

Tween linearEaseIn, linearEaseOut, linearEaseBoth, quadEaseIn, quadEaseOut,
quadEaseBoth, cubicEaseIn, cubicEaseBoth, cubicEaseOut,
quartEaseIn, quartEaseOut, quartEaseBoth, quintEaseIn,
quintEaseOut, quintEaseBoth, sineEaseIn, sineEaseOut, sineEaseBoth,
circEaseIn, circEaseOut, circEaseBoth, expoEaseIn, expoEaseOut,
expoEaseBoth, backEaseIn, backEaseOut, backEaseBoth, bounceEaseIn,
bounceEaseOut, bounceEaseBoth, elasticEaseIn, elasticEaseOut,
elasticEaseBoth;

TweenSequence tweenSequence;

float duration = 100;
float xBegin = 0;
float xEnd = 390;
float delay = 0;

public void setup() {
  size(400, 450, P3D);

  frameRate(30);
  background(0);

  linearEaseIn = new Tween(this, "Tween1", xBegin, xEnd, duration, Tween.FRAMES, delay, new Linear(), Tween.EASE_IN);
  linearEaseOut = new Tween(this, "Tween2", xBegin, xEnd, duration, Tween.FRAMES, delay, new Linear(), Tween.EASE_OUT);
  linearEaseBoth = new Tween(this, "Tween3", xBegin, xEnd, duration, Tween.FRAMES, delay, new Linear(), Tween.EASE_BOTH);

  quadEaseIn = new Tween(this, "Tween1", xBegin, xEnd, duration, Tween.FRAMES, delay, new Quad(), Tween.EASE_IN);
  quadEaseOut = new Tween(this, "Tween2", xBegin, xEnd, duration, Tween.FRAMES, delay, new Quad(), Tween.EASE_OUT);
  quadEaseBoth = new Tween(this, "Tween3", xBegin, xEnd, duration, Tween.FRAMES, delay, new Quad(), Tween.EASE_BOTH);

  cubicEaseIn = new Tween(this, "Tween1", xBegin, xEnd, duration, Tween.FRAMES, delay, new Cubic(), Tween.EASE_IN);
  cubicEaseOut = new Tween(this, "Tween2", xBegin, xEnd, duration, Tween.FRAMES, delay, new Cubic(), Tween.EASE_OUT);
  cubicEaseBoth = new Tween(this, "Tween3", xBegin, xEnd, duration, Tween.FRAMES, delay, new Cubic(), Tween.EASE_BOTH);

  quartEaseIn = new Tween(this, "Tween1", xBegin, xEnd, duration, Tween.FRAMES, delay, new Quart(), Tween.EASE_IN);
  quartEaseOut = new Tween(this, "Tween2", xBegin, xEnd, duration, Tween.FRAMES, delay, new Quart(), Tween.EASE_OUT);
  quartEaseBoth = new Tween(this, "Tween3", xBegin, xEnd, duration, Tween.FRAMES, delay, new Quart(), Tween.EASE_BOTH);

  quintEaseIn = new Tween(this, "Tween1", xBegin, xEnd, duration, Tween.FRAMES, delay, new Quint(), Tween.EASE_IN);
  quintEaseOut = new Tween(this, "Tween2", xBegin, xEnd, duration, Tween.FRAMES, delay, new Quint(), Tween.EASE_OUT);
  quintEaseBoth = new Tween(this, "Tween3", xBegin, xEnd, duration, Tween.FRAMES, delay, new Quint(), Tween.EASE_BOTH);

  sineEaseIn = new Tween(this, "Tween1", xBegin, xEnd, duration, Tween.FRAMES, delay, new Sine(), Tween.EASE_IN);
  sineEaseOut = new Tween(this, "Tween2", xBegin, xEnd, duration, Tween.FRAMES, delay, new Sine(), Tween.EASE_OUT);
  sineEaseBoth = new Tween(this, "Tween3", xBegin, xEnd, duration, Tween.FRAMES, delay, new Sine(), Tween.EASE_BOTH);

  circEaseIn = new Tween(this, "Tween1", xBegin, xEnd, duration, Tween.FRAMES, delay, new Circ(), Tween.EASE_IN);
  circEaseOut = new Tween(this, "Tween2", xBegin, xEnd, duration, Tween.FRAMES, delay, new Circ(), Tween.EASE_OUT);
  circEaseBoth = new Tween(this, "Tween3", xBegin, xEnd, duration, Tween.FRAMES, delay, new Circ(), Tween.EASE_BOTH);

  expoEaseIn = new Tween(this, "Tween1", xBegin, xEnd, duration, Tween.FRAMES, delay, new Expo(), Tween.EASE_IN);
  expoEaseOut = new Tween(this, "Tween2", xBegin, xEnd, duration, Tween.FRAMES, delay, new Expo(), Tween.EASE_OUT);
  expoEaseBoth = new Tween(this, "Tween3", xBegin, xEnd, duration, Tween.FRAMES, delay, new Expo(), Tween.EASE_BOTH);

  backEaseIn = new Tween(this, "Tween1", xBegin, xEnd, duration, Tween.FRAMES, delay, new Back(), Tween.EASE_IN);
  backEaseOut = new Tween(this, "Tween2", xBegin, xEnd, duration, Tween.FRAMES, delay, new Back(), Tween.EASE_OUT);
  backEaseBoth = new Tween(this, "Tween3", xBegin, xEnd, duration, Tween.FRAMES, delay, new Back(), Tween.EASE_BOTH);

  bounceEaseIn = new Tween(this, "Tween1", xBegin, xEnd, duration, Tween.FRAMES, delay, new Bounce(), Tween.EASE_IN);
  bounceEaseOut = new Tween(this, "Tween2", xBegin, xEnd, duration, Tween.FRAMES, delay, new Bounce(), Tween.EASE_OUT);
  bounceEaseBoth = new Tween(this, "Tween3", xBegin, xEnd, duration, Tween.FRAMES, delay, new Bounce(), Tween.EASE_BOTH);

  elasticEaseIn = new Tween(this, "Tween1", xBegin, xEnd, duration, Tween.FRAMES, delay, new Elastic(), Tween.EASE_IN);
  elasticEaseOut = new Tween(this, "Tween2", xBegin, xEnd, duration, Tween.FRAMES, delay, new Elastic(), Tween.EASE_OUT);
  elasticEaseBoth = new Tween(this, "Tween3", xBegin, xEnd, duration, Tween.FRAMES, delay, new Elastic(), Tween.EASE_BOTH);

  tweenSequence = new TweenSequence(this, new Object[]{
    linearEaseIn, linearEaseOut, linearEaseBoth, quadEaseIn, quadEaseOut, quadEaseBoth, cubicEaseIn, cubicEaseBoth, cubicEaseOut, quartEaseIn, quartEaseOut, quartEaseBoth, quintEaseIn, quintEaseOut, quintEaseBoth, sineEaseIn, sineEaseOut, sineEaseBoth, circEaseIn, circEaseOut, circEaseBoth, expoEaseIn, expoEaseOut, expoEaseBoth, backEaseIn, backEaseOut, backEaseBoth, bounceEaseIn, bounceEaseOut, bounceEaseBoth, elasticEaseIn, elasticEaseOut, elasticEaseBoth        }
  );

  tweenSequence.start();
}

public void draw() {
  background(0);

  tweenSequence.update();

  fill(140, 255, 100);
  rect(linearEaseIn.position, 10, 10, 10);
  rect(linearEaseOut.position, 20, 10, 10);
  rect(linearEaseBoth.position, 30, 10, 10);

  fill(100, 0, 100);
  rect(quadEaseIn.position, 50, 10, 10);
  rect(quadEaseOut.position, 60, 10, 10);
  rect(quadEaseBoth.position, 70, 10, 10);

  fill(100, 100, 50);
  rect(cubicEaseIn.position, 90, 10, 10);
  rect(cubicEaseOut.position, 100, 10, 10);
  rect(cubicEaseBoth.position, 110, 10, 10);

  fill(125, 0, 255);
  rect(quartEaseIn.position, 130, 10, 10);
  rect(quartEaseOut.position, 140, 10, 10);
  rect(quartEaseBoth.position, 150, 10, 10);

  fill(0, 125, 255);
  rect(quintEaseIn.position, 170, 10, 10);
  rect(quintEaseOut.position, 180, 10, 10);
  rect(quintEaseBoth.position, 190, 10, 10);

  fill(255, 0, 255);
  rect(sineEaseIn.position, 210, 10, 10);
  rect(sineEaseOut.position, 220, 10, 10);
  rect(sineEaseBoth.position, 230, 10, 10);

  fill(255, 0, 0);
  rect(circEaseIn.position, 250, 10, 10);
  rect(circEaseOut.position, 260, 10, 10);
  rect(circEaseBoth.position, 270, 10, 10);

  fill(255, 100, 0);
  rect(expoEaseIn.position, 290, 10, 10);
  rect(expoEaseOut.position, 300, 10, 10);
  rect(expoEaseBoth.position, 310, 10, 10);

  fill(100, 255, 0);
  rect(backEaseIn.position, 330, 10, 10);
  rect(backEaseOut.position, 340, 10, 10);
  rect(backEaseBoth.position, 350, 10, 10);

  fill(180, 255, 255);
  rect(bounceEaseIn.position, 370, 10, 10);
  rect(bounceEaseOut.position, 380, 10, 10);
  rect(bounceEaseBoth.position, 390, 10, 10);

  fill(0, 255, 255);
  rect(elasticEaseIn.position, 410, 10, 10);
  rect(elasticEaseOut.position, 420, 10, 10);
  rect(elasticEaseBoth.position, 430, 10, 10);
}

void tweenStartedEvent(Tween _t) {
  println(_t+" started");
}

void tweenEndedEvent(Tween _t) {
  println(_t + " ended");
}

void tweenPausedEvent(Tween _t) {
  println(_t + " paused");
}

void tweenResumedEvent(Tween _t) {
  println(_t + " resumed");
}

public void keyPressed() {
  if (key == ' ')
    tweenSequence.start();
}

